<html>
<head>
<title>How to create a simulation</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="highlight.css" type="text/css">
</head>

<body bgcolor="#FFFFFF" text="#000000">
<p><font size="6"><i><b>How to create a Simulation</b></i></font></p>
<p><font size="4">In this HowTo we will focus on the steps involved in creating 
  a simulation. The truth is, we already have everything we need to know to create 
  a simulation. We can build control aspects to implement the rules governing 
  our simulation. We can implement agent aspects, which can interact with the 
  world through perceptors and effectors. Now, all we have to do is bundle all 
  this different things together into a simulation.</font></p>
<p><font size="4">A simulation is comprised of two things. A bundle including 
  all the custom elements making up the simulation (control aspects, agent aspects, 
  custom perceptors and effectors) and a so-called assembly script, which builds 
  the object hierarchy necessary to perform the simulation. As the first aspect, 
  building a bundle has already been described in a previous HowTo, we will focus 
  on the assembly script.</font></p>
<p><font size="4">The assembly script is just like any other Ruby script. If we 
  look at the Survival sample simulation, we see that a subdirectory 'survival' 
  is created under the path of the simulator executable (app/simulator). It contains 
  a script called 'survival.rb'. The name of the directory and the script MUST 
  match (except for the rb-extension). The simulator is started with the command-line 
  parameter 'survival', causing it to look for a survival.rb script in the survival 
  subdirectory. We will now go through the survival.rb assembly script line by 
  line:</font></p>
<pre># Import classes of this simulation description
   importBundle('survival/survival');
</pre>
<p><font size="4">First, we begin by importing the bundle containing our custom 
  classes. This call adds them to the class object framework of the object hierarchy</font><font size="4">, 
  making the classes available for future calls.</font></p>
<pre># create the control aspect
   cd ('/usr/scene');</pre>
<pre>   controlAspect = new ('SurvivalControlAspect', '_control');</pre>
<p><font size="4">Then we select the 'scene' object. The root of our hierarchical 
  scene structure. It is always located at the path '/usr/scene'. There we create 
  an instance of SurvivalControlAspect ... a class contained in the previously 
  loaded bundle.</font></p>
<pre># create world and space aspects
   cd ('/usr/scene');

   world = new ('kerosin/World', '_world');
   world.setGravity(0.0, -9.81, 0.0);

   new ('kerosin/Space', '../_space');</pre>
<p><font size="4">Next, we create two important classes for the physics aspect: 
  a world and a space. The world is where all dynamics objects (Bodies) live and 
  the space is, where the geometry aspects can collide.</font></p>
<pre># setup camera
   trans = new ('kerosin/Transform', '../camera');
   trans.setLocalPos(0.0, 0.0, 10.0);

   new ('kerosin/Camera', 'camera');

   body = new ('kerosin/Body', '../_physics');
   body.useGravity(false);

   new ('kerosin/FPSController', 'fps');

   collider = new ('kerosin/SphereCollider', '../_geometry');
   collider.setRadius(2.0);

   light = new ('kerosin/Light', '../../_light');
   light.setRadius(50.0);
   light.setDiffuseColor(1.0, 1.0, 1.0);
</pre>
<p><font size="4">The above calls add a camera object to the scene. This is necessary 
  to be able to visualize the simulation. At first, we add a transform node. Under 
  it we attach a kerosin::Camera object. It has a physics aspect (kerosin::Body), 
  which in turn has an FPSController attached. This controller receives the key-presses 
  and mouse movements and translates these to physical movements of the camera. 
  Hence, the connection to the Body class. Our camera is also capable of colliding 
  with other objects in the world, so we add a SphereCollider with radius 2. For 
  some special FX we have also endowed the camera with a dynamic light.</font></p>
<pre># add arena
   cd ('/usr/scene');
   trans = new ('kerosin/Transform', 'arena');
   trans.setLocalPos(0.0, 0.0, 0.0);
   mesh = new ('kerosin/StaticMesh', '_visual');
   mesh.load('model/arena.void');

# floor
   pc = new ('kerosin/PlaneCollider', '../pc');
   pc.setParams(0.0, 1.0 ,0.0, 0.0); 

#lights
   trans = new ('kerosin/Transform', '../../light0');
   trans.setLocalPos(0.0, 15.0, 0.0);
   light = new ('kerosin/Light', '_light');
   light.setRadius(80.0);
   light.setDiffuseColor(1.0, 1.0, 1.0);</pre>
<p><font size="4">The above blocks load a very simple rectangular 'playing field' 
  and add a planar collision geometry (geometry aspect), as well as another dynamic 
  light. </font></p>
<p># add slow<br>
</p>
<pre>   cd ('/usr/scene');

   trans = new ('kerosin/Transform', 'slow');
   trans.setLocalPos(-12.5, 1.0, -12.5);

   visual = new ('kerosin/StaticMesh', '_visual');
   visual.load('model/slow.void');

   physics = new ('kerosin/Body', '../_physics');
   physics.setSphere(1.0, 1.0);
   physics.setMass(1.0);
   physics.setMaxSpeed(3.0);

   geometry = new ('kerosin/SphereCollider', '../_geometry');
   geometry.setRadius(1.0);

   agent = new ('SurvivalAgentAspect', '../_agent');
</pre>
<p><font size="4">Here we add the first agent to the world. We begin by giving 
  it a starting position (the transform node). Then we add the visual aspect (load 
  the slow.void mesh), physics aspect</font><font size="4">, geometry aspect and 
  agent aspect (SurvivalAgentAspect).</font><br>
</p>
<pre># add fast
   cd ('/usr/scene');


   trans = new ('kerosin/Transform', 'fast');
   trans.setLocalPos(12.5, 1.0, 12.5);


   visual = new ('kerosin/StaticMesh', '_visual');
   visual.load('model/fast.void');


   physics = new ('kerosin/Body', '../_physics');
   physics.setSphere(1.0, 1.0);
   physics.setMass(1.0);
   physics.setMaxSpeed(10.0);


   geometry = new ('kerosin/SphereCollider', '../_geometry');
   geometry.setRadius(1.0);


   agent = new ('SurvivalAgentAspect', '../_agent');
</pre>
<p><font size="4">This adds the second agent to the world. Almost identical to 
  the second agent, except it has a higher maximum speed and a different visual 
  aspect. </font><br>
</p>
<pre>
# add food
   cd ('/usr/scene');


   trans = new ('kerosin/Transform', 'food');
   trans.setLocalPos(0.0, 1.0, 0.0);


   visual = new ('kerosin/StaticMesh', '_visual');
   visual.load('model/food.void');</pre>
<p><font size="4">Last but not least, the 'food' object is added. As one can tell, 
  it has only 'visual' character. The control aspect determines internally if 
  one of the agents has reached the food (see SurvivalControlAspect).</font></p>
<p><font size="4">As one can see, creating assembly scripts is straight-forward. 
  One only has to keep track of what one is building up in the object hierarchy. 
  After the script is executed, the simulation is run automatically.</font></p>
<p>&nbsp;</p>
</body>
</html>

